﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.ComponentModel;
using Microsoft.WindowsAPICodePack.Shell;
using System.Collections.ObjectModel;

namespace TouchExplorer.Entities
{
    [Serializable]
    public class Favorite
    {
        [XmlAttribute]
        public string Path { get; set; }

        [XmlAttribute]
        public string EltType { get; set; }

        public Favorite()
        {            
        }

        public Favorite(TouchFileElementBase elt)
        {
            if (elt is TouchDirectory) EltType = "dir";
            else EltType = "file";

            Path = elt.FullPath;
        }

        public TouchFileElementBase GetElement()
        {
            if (EltType == "dir")
            {
                if (Directory.Exists(Path)) 
                    return new TouchDirectory(new DirectoryInfo(Path));
                else
                    return new TouchDirectory(ShellObject.FromParsingName(Path));
            }
            else
            {
                if (File.Exists(Path))
                    return new TouchFile(new FileInfo(Path));
                else
                    return new TouchFile(ShellObject.FromParsingName(Path));
            }
        }
    }

    [Serializable]
    public class FavoritesViewModel : INotifyPropertyChanged
    {
        private static string _path = "favorites.xml";

        private List<Favorite> _favorites = new List<Favorite>();

        public List<Favorite> Favorites
        {
            get
            {
                return this._favorites;
            }
            set
            {
                this._favorites = value;
            }
        }

        private static XmlSerializer serializer = new XmlSerializer(typeof(FavoritesViewModel));

        [XmlIgnore]
        private ObservableCollection<TouchFileElementBase> _elements = new ObservableCollection<TouchFileElementBase>();

        [XmlIgnore]
        public ObservableCollection<TouchFileElementBase> Elements
        {
            get
            {
                return this._elements;
            }
            set
            {
                this._elements = value;
            }
        }

        public void Save()
        {
            using (StreamWriter writer = new StreamWriter(_path))
            {
                serializer.Serialize(writer, this);
            }
        }

        public static FavoritesViewModel Load()
        {
            if (!File.Exists(_path))
                return new FavoritesViewModel();

            try
            {
                using (StreamReader reader = new StreamReader(_path))
                {
                    var res = (FavoritesViewModel)serializer.Deserialize(reader);
                    foreach (var favorite in res.Favorites)
                    {
                        try
                        {
                            res.Elements.Add(favorite.GetElement());
                        }
                        catch (Exception)
                        {                            
                        }
                    }

                    return res;
                }
            }
            catch (Exception)
            {
                return new FavoritesViewModel();
            }
        }

        public void Add(TouchFileElementBase elt)
        {
            Favorites.Add(new Favorite(elt));
            Elements.Add(elt);
            elt.IsFavorite = true;
            this.Save();
        }

        public bool Has(TouchFileElementBase elt)
        {
            return Favorites.Any(s => s.Path == elt.FullPath);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string p)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(p));
        }

        public void Add(IEnumerable<TouchFileElementBase> elt)
        {
            foreach (var touchFile in elt)
            {
                Add(touchFile);
            }
        }

        public void Remove(TouchFileElementBase elt)
        {
            var fav = Favorites.FirstOrDefault(f => f.Path == elt.FullPath);
            Favorites.Remove(fav);
            Elements.Remove(elt);
            elt.IsFavorite = false;
            this.Save();
        }
    }
}
